//-----------------------------------------------
// author:   wzx
// update:   2022/5/3
//			 2022/5/3: 返回填充面积，填充数可变
// describe: 改进种子填充算法
// 参考资料: https://pengfeixc.com/blog/60d06420e97367196dce3efb
//-----------------------------------------------
#include "headfile.h"
#include "seedfilling.h"

uint8 stack_flag = 0;
uint8 width_stack[50];
uint8 height_stack[50];

uint8 fill_num;  // 填充数
extern uint8 flag_img[region_height][region_width];

// 处理二值化后的图像
uint16 start_fill(uint8 *image, uint8 h, uint8 w)  // 图像 行 列
{
	uint16 square = 0; // 连通域面积
	uint8 kind;  // 初始点类型
	uint8 temp_kind;  // 当前点类型
	bool reach_left = false;
	bool reach_right = false;
	uint8 temp_h, temp_w;  // 当前出栈点
	stack_in(h, w);  // 初始点入栈
	kind = *(image + h * region_width + w);
	temp_kind = kind; 
	while (stack_empty() == false)
	{
		stack_out(&temp_h, &temp_w);
		reach_left = false;
		reach_right = false;
		do {
			temp_h = temp_h == 0 ? 0 : --temp_h;  // 上移一位
			temp_kind = *(image + temp_h * region_width + temp_w);  // 读取当前种类
		} while ((temp_h!=0) && (temp_kind== kind));
		if(temp_kind != kind)
			temp_h++;
		// 向下
		do {
			*(image + temp_h * region_width + temp_w) = fill_num;  //---------------------填充数
			flag_img[temp_h][temp_w] = fill_num;
			square++;
			if ((temp_w != 0) && (*(image + temp_h * region_width + temp_w - 1) == kind) && reach_left==false)
			{
				stack_in(temp_h, temp_w - 1);
				reach_left = true;
			}
			else if ((*(image + temp_h * region_width + temp_w - 1) != kind))
			{
				reach_left = false;
			}
			if ((temp_w != region_width-1) && (*(image + temp_h * region_width + temp_w + 1) == kind) && reach_right == false)
			{
				stack_in(temp_h, temp_w + 1);
				reach_right = true;
			}
			else if ((*(image + temp_h * region_width + temp_w + 1) != kind))
			{
				reach_right = false;
			}
			temp_h = (temp_h==region_height-1) ? region_height - 1 : ++temp_h;  // 下移一位
			temp_kind = *(image + temp_h * region_width + temp_w);  // 读取当前种类
		} while ((temp_h != region_height - 1) && (temp_kind == kind));
		// 最下面一行单独处理
		if (temp_h == region_height - 1)
		{
			*(image + temp_h * region_width + temp_w) = fill_num;  //---------------------填充数
			flag_img[temp_h][temp_w] = fill_num;
			square++;
			if ((temp_w != 0) && (*(image + temp_h * region_width + temp_w - 1) == kind) && reach_left == false)
			{
				stack_in(temp_h, temp_w - 1);
				reach_left = true;
			}
			if ((temp_w != region_width - 1) && (*(image + temp_h * region_width + temp_w + 1) == kind) && reach_right == false)
			{
				stack_in(temp_h, temp_w + 1);
				reach_right = true;
			}
		}	
	}
	return square;
}

// 入栈
// flag指向下一个空位
void stack_in(uint8 h, uint8 w)
{
	height_stack[stack_flag] = h;
	width_stack[stack_flag] = w;
	stack_flag++;
}

// 出栈
void stack_out(uint8 *h, uint8 *w)
{
	stack_flag--;
	*h = height_stack[stack_flag];
	*w = width_stack[stack_flag];
	height_stack[stack_flag] = 0;
	width_stack[stack_flag] = 0;
}

// 是否栈空
bool stack_empty()
{
	if (stack_flag == 0)
		return true;
	else
		return false;
}
